package cn.itrip.controller;

import cn.itrip.beans.dto.Dto;
import cn.itrip.beans.pojo.*;
import cn.itrip.beans.vo.order.ItripAddHotelOrderVO;
import cn.itrip.beans.vo.order.ItripModifyHotelOrderVO;
import cn.itrip.beans.vo.order.RoomStoreVO;
import cn.itrip.beans.vo.order.ValidateRoomStoreVO;
import cn.itrip.common.*;
import cn.itrip.service.itripHotel.ItripHotelService;
import cn.itrip.service.itripHotelOrder.ItripHotelOrderService;
import cn.itrip.service.itripHotelRoom.ItripHotelRoomService;
import cn.itrip.service.itripHotelTempStore.ItripHotelTempStoreService;
import cn.itrip.service.itripTradeEnds.ItripTradeEndsService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ClassName HotelOrderController
 * @Description TODO
 * @Author yaozhaobao
 * @Date 2020/12/29 16:51
 * @Version 1.0
 **/
@RestController
@RequestMapping("/api/hotelorder")
public class HotelOrderController {


    @Autowired
    ItripHotelService itripHotelService;

    @Autowired
    ItripHotelRoomService itripHotelRoomService;

    @Autowired
    ItripHotelOrderService itripHotelOrderService;

    @Autowired
    ValidationToken validationToken;

    @Autowired
    SystemConfig systemConfig;

    @Autowired
    ItripHotelTempStoreService itripHotelTempStoreService;

    @Autowired
    ItripTradeEndsService itripTradeEndsService;

    /**
     * 下单前查询指定日期内，某个房间类型，库存数
     * @param validateRoomStoreVO
     * @return
     */
    @RequestMapping("/getPreorderinfo")
    public Dto<RoomStoreVO> getPreOrderInfo(@RequestBody ValidateRoomStoreVO validateRoomStoreVO,HttpServletRequest request){
        //1.登录认证，token认证，略
        String token=  request.getHeader("token");
        String agent= request.getHeader("user-agent");
        if(!validationToken.validateToken(token,agent)){
            return  DtoUtil.returnFail("token无效，请重新登录",ErrorCode.AUTH_TOKEN_INVALID);
        }

        //2.入参条件，时间，房型，酒店非空判断，为空则返回 略
        if(EmptyUtils.isEmpty(validateRoomStoreVO.getRoomId())){
            return DtoUtil.returnFail("roomId不能为空",ErrorCode.HOTEL_ILLEGAL_ARGS);
        }
        if(EmptyUtils.isEmpty(validateRoomStoreVO.getHotelId())){
            return DtoUtil.returnFail("hotelId不能为空",ErrorCode.HOTEL_ILLEGAL_ARGS);
        }
        if(EmptyUtils.isEmpty(validateRoomStoreVO.getCheckInDate())){
            return DtoUtil.returnFail("入驻时间不能为空",ErrorCode.HOTEL_ILLEGAL_ARGS);
        }
        if(EmptyUtils.isEmpty(validateRoomStoreVO.getCheckOutDate())){
            return DtoUtil.returnFail("退房时间不能为空",ErrorCode.HOTEL_ILLEGAL_ARGS);
        }


        //3.查询酒店的详细信息---hotelName
        try {
            ItripHotel itripHotel= itripHotelService.getItripHotelById(validateRoomStoreVO.getHotelId());
            //4.查询房间的详细信息---price
            ItripHotelRoom itripHotelRoom =itripHotelRoomService.getItripHotelRoomById(validateRoomStoreVO.getRoomId());
            //5.查询酒店,房间,日期内的最小库存数
            Map<String,Object> map= new HashMap<String,Object>();
            map.put("startTime",validateRoomStoreVO.getCheckInDate());
            map.put("endTime",validateRoomStoreVO.getCheckOutDate());
            map.put("roomId",validateRoomStoreVO.getRoomId());
            map.put("hotelId",validateRoomStoreVO.getHotelId());


            List<ItripHotelTempStore>  list=itripHotelOrderService.queryRoomStore(map);

            //6.封装结果集到roomStoreVo
            RoomStoreVO roomStoreVO=new RoomStoreVO();
            roomStoreVO.setCheckInDate(validateRoomStoreVO.getCheckInDate());
            roomStoreVO.setCheckOutDate(validateRoomStoreVO.getCheckOutDate());
            roomStoreVO.setCount(validateRoomStoreVO.getCount());
            roomStoreVO.setHotelName(itripHotel.getHotelName());
            roomStoreVO.setPrice(BigDecimal.valueOf(itripHotelRoom.getRoomPrice()));
            roomStoreVO.setStore(list.get(0).getStore());

            //7.返回数据
            return DtoUtil.returnDataSuccess(roomStoreVO);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return  DtoUtil.returnFail("未知异常", ErrorCode.AUTH_UNKNOWN);
    };




    @RequestMapping("/validateroomstore")
    public Dto validateroomstore(@RequestBody ValidateRoomStoreVO validateRoomStoreVO,HttpServletRequest request){
        //1.登录认证，token认证，略
        String token=  request.getHeader("token");
        String agent= request.getHeader("user-agent");
        if(!validationToken.validateToken(token,agent)){
            return  DtoUtil.returnFail("token无效，请重新登录",ErrorCode.AUTH_TOKEN_INVALID);
        }

        //2.入参条件，时间，房型，酒店非空判断，为空则返回 略
        if(EmptyUtils.isEmpty(validateRoomStoreVO.getRoomId())){
            return DtoUtil.returnFail("roomId不能为空",ErrorCode.HOTEL_ILLEGAL_ARGS);
        }
        if(EmptyUtils.isEmpty(validateRoomStoreVO.getHotelId())){
            return DtoUtil.returnFail("hotelId不能为空",ErrorCode.HOTEL_ILLEGAL_ARGS);
        }
        if(EmptyUtils.isEmpty(validateRoomStoreVO.getCheckInDate())){
            return DtoUtil.returnFail("入驻时间不能为空",ErrorCode.HOTEL_ILLEGAL_ARGS);
        }
        if(EmptyUtils.isEmpty(validateRoomStoreVO.getCheckOutDate())){
            return DtoUtil.returnFail("退房时间不能为空",ErrorCode.HOTEL_ILLEGAL_ARGS);
        }
        if(EmptyUtils.isEmpty(validateRoomStoreVO.getCount())&&validateRoomStoreVO.getCount()>0){
            return DtoUtil.returnFail("退房时间不能为空",ErrorCode.HOTEL_ILLEGAL_ARGS);
        }

        //3.所选的房间数量是否小于此时的库存数
        Map<String,Object> map= new HashMap<String,Object>();
        map.put("startTime",validateRoomStoreVO.getCheckInDate());
        map.put("endTime",validateRoomStoreVO.getCheckOutDate());
        map.put("roomId",validateRoomStoreVO.getRoomId());
        map.put("hotelId",validateRoomStoreVO.getHotelId());
        boolean rs =itripHotelOrderService.valideroomcount(validateRoomStoreVO.getCount(),map);
        if(rs) {
            return DtoUtil.returnDataSuccess(rs);
        }else{
            return DtoUtil.returnFail("库存不足",ErrorCode.HOTEL_ILLEGAL_ARGS);
        }
    }

    @RequestMapping(value = "/addhotelorder",method = RequestMethod.GET)
    public  Dto<Map<String,String>>  addHotelOrder(@RequestBody ItripAddHotelOrderVO  itripAddHotelOrderVO,HttpServletRequest request){
        //验证登录token
        //1.登录认证，token认证，略
        String token=  request.getHeader("token");
        String agent= request.getHeader("user-agent");
        if(!validationToken.validateToken(token,agent)){
            return  DtoUtil.returnFail("token无效，请重新登录",ErrorCode.AUTH_TOKEN_INVALID);
        }

        //验证表单
        if(EmptyUtils.isEmpty(itripAddHotelOrderVO)||
                EmptyUtils.isEmpty(itripAddHotelOrderVO.getHotelId())
                ||EmptyUtils.isEmpty(itripAddHotelOrderVO.getCheckInDate())
                ||EmptyUtils.isEmpty(itripAddHotelOrderVO.getCheckOutDate())
                ||EmptyUtils.isEmpty(itripAddHotelOrderVO.getCount())||itripAddHotelOrderVO.getCount()<0){
            return DtoUtil.returnFail("请求参数有误",ErrorCode.HOTEL_ILLEGAL_ARGS);
        }

        //验证库存
        //3.所选的房间数量是否小于此时的库存数
        Map<String,Object> map= new HashMap<String,Object>();
        map.put("startTime",itripAddHotelOrderVO.getCheckInDate());
        map.put("endTime",itripAddHotelOrderVO.getCheckOutDate());
        map.put("roomId",itripAddHotelOrderVO.getRoomId());
        map.put("hotelId",itripAddHotelOrderVO.getHotelId());
        boolean rs =itripHotelOrderService.valideroomcount(itripAddHotelOrderVO.getCount(),map);
        if(!rs) {
            return DtoUtil.returnFail("库存不足",ErrorCode.HOTEL_ILLEGAL_ARGS);
        }
        //生成订单
        //封装订单数据
        ItripHotelOrder itripHotelOrder =new ItripHotelOrder();
        try {
            ItripHotel itripHotel =itripHotelService.getItripHotelById(itripAddHotelOrderVO.getHotelId());
            itripHotelOrder.setHotelName(itripHotel.getHotelName());
        } catch (Exception e) {
            e.printStackTrace();
        }
        //订单类型
        itripHotelOrder.setOrderType(1);
        BeanUtils.copyProperties(itripAddHotelOrderVO,itripHotelOrder);
        //下单人 创建人----token
        ItripUser itripUser =validationToken.getCurrentUser(token);
        itripHotelOrder.setCreatedBy(itripUser.getId());
        itripHotelOrder.setUserId(itripUser.getId());
        itripHotelOrder.setCreationDate(new Date());
        //住店相关的人
        List<ItripUserLinkUser> linkUsers =itripAddHotelOrderVO.getLinkUser();

        if(EmptyUtils.isNotEmpty(linkUsers)){
            StringBuffer stringBuffer =new StringBuffer();
            for(int i=0;;){
                stringBuffer.append(linkUsers.get(i).getLinkUserName());
                if(++i<linkUsers.size()){
                    stringBuffer.append(",");
                    continue;
                }
                break;
            }
            itripHotelOrder.setLinkUserName(stringBuffer.toString());
        }

        //预定天数
        List<Date>  dates= DateUtil.getBetweenDates(itripAddHotelOrderVO.getCheckInDate(),itripAddHotelOrderVO.getCheckOutDate());
        int days=dates.size();
        itripHotelOrder.setBookingDays(days);
        int booktype=0;
        //订单来源哪个平台
        if(token.startsWith("token:MOBILE-")){
            booktype=1;
        }
        itripHotelOrder.setBookType(booktype);

        //订单状态，生成订单号
        //生成规则:  机器码+时间戳+6位数随机数 md5
        StringBuilder stringBuilder=new StringBuilder(systemConfig.getMachineCode());
        stringBuilder.append( new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
        StringBuilder rand6=new StringBuilder(itripAddHotelOrderVO.getHotelId()+"");
        rand6.append(itripAddHotelOrderVO.getRoomId());
        rand6.append(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
        String md5=MD5.getMd5(rand6.toString(),6);
        stringBuilder.append(md5);
        itripHotelOrder.setOrderNo(stringBuilder.toString());

        //订单的类型，未支付
        //itripHotelOrder.setPayType(1);
        itripHotelOrder.setOrderStatus(0); //未支付
        //订单金额
        try {
            BigDecimal payAmount=itripHotelOrderService.payAmount((days-1)*itripAddHotelOrderVO.getCount(),itripAddHotelOrderVO.getRoomId());
            itripHotelOrder.setPayAmount(payAmount.doubleValue());
        } catch (Exception e) {
            e.printStackTrace();
            return DtoUtil.returnFail("数据转换异常",ErrorCode.AUTH_UNKNOWN);
        }

        //添加订单到数据库中
        try {
            itripHotelOrderService.itriptxAddItripHotelOrder(itripHotelOrder);
            return  DtoUtil.returnSuccess();
        } catch (Exception e) {
            e.printStackTrace();
            return DtoUtil.returnFail("數據庫異常",ErrorCode.HOTEL_SQLEXCEPTION);
        }
    }


    @RequestMapping(value = "/updateorderstatusandpaytype")
    public Dto updateOrderStatusAndPayType(@RequestBody ItripModifyHotelOrderVO itripModifyHotelOrderVO,HttpServletRequest request){
        //1.登录校验
        //1.登录认证，token认证，略
        String token=  request.getHeader("token");
        String agent= request.getHeader("user-agent");
        if(!validationToken.validateToken(token,agent)){
            return  DtoUtil.returnFail("token无效，请重新登录",ErrorCode.AUTH_TOKEN_INVALID);
        }


        //2.参数判断
        if(itripModifyHotelOrderVO==null||
                itripModifyHotelOrderVO.getId()==null||
                itripModifyHotelOrderVO.getId()==0||
                itripModifyHotelOrderVO.getPayType()==null
                ||itripModifyHotelOrderVO.getPayType()==0){
            return DtoUtil.returnFail("请求参数有误",ErrorCode.HOTEL_ILLEGAL_ARGS);
        }

        try {
            ItripHotelOrder order= itripHotelOrderService.getItripHotelOrderById(itripModifyHotelOrderVO.getId());
            //验证商品是否支持线下支付
            boolean rs= itripHotelOrderService.isOffLinePaymentSupport(order.getRoomId());
            if(!rs){
                return DtoUtil.returnFail("对不起不支持线下支付",ErrorCode.HOTEL_ILLEGAL_ARGS);
            }

            //更新订单状态和支付类型
            order.setPayType(itripModifyHotelOrderVO.getPayType());

            //设置订单状态  已经支付
            order.setOrderStatus(2);

            ItripUser user = validationToken.getCurrentUser(token);
            order.setModifiedBy(user.getId());
            order.setModifyDate(new Date());

            //减少库存数量
            int rs1=itripHotelTempStoreService.flushTempStore(order);



            int rs2= itripHotelOrderService.itriptxModifyItripHotelOrder(order);
            if(rs2>0&&rs1>0){
                return  DtoUtil.returnSuccess("修改订单状态成功");
            }

        } catch (Exception e) {
            e.printStackTrace();

        }
        return  DtoUtil.returnFail("未知错误","100003");
    }


    /**
     * 定期扫描订单表  超过两个小时没有支付的订单改成 已取消状态
     */
    @Scheduled(cron="0 0/30 * *  * *")
    public void cancelOrderTimeOut(){
        try {
            itripHotelOrderService.cancelOrderTimeOut();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    @Scheduled(cron="0 0 15 0/1  * *")
    public void changOrderTocommit(){
        try {
            itripHotelOrderService.changOrderToCommit();
        }catch (Exception e){
            e.printStackTrace();
        }

    }

    /**
     * 用户支付成功以后，订单数据放入一个tradeend表，扫描这个表，减少库存
     */
    @Scheduled(cron="* 7/1 17 * * *")
    public void job(){
        System.out.println("==============");
        //1 首先获取tradeend表中 flag为1的订单
            Map<String,Object> params=new HashMap<>();
            params.put("oldflag",0);
            params.put("flag",1);
        try {
            Integer count = itripTradeEndsService.itriptxModifyItripTradeEnds(params);
            if(count>0){
                //2.根据flag为1的订单，获取订单的号，入驻时间，退房时间，酒店房间id 数量 ，减少库存
             List<ItripTradeEnds> itripTradeEndsList=itripTradeEndsService.getItripTradeEndsListByMap(params);
             itripHotelOrderService.itriptxFlushTempStore(itripTradeEndsList);
                //3.tradend表中的订单flag状态进行修改
                params.put("oldflag",1);
                params.put("flag",2);
               itripTradeEndsService.itriptxModifyItripTradeEnds(params);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }














}
